//
//  XJSqlite3ModelManage.swift
//  XJSqlite3Tool
//
//  Created by shanlin on 2017/7/1.
//  Copyright © 2017年 善林(中国)金融信息服务有限公司. All rights reserved.
//

import UIKit

class XJSqlite3ModelManager: NSObject {}


//============================================================
//       Check 1 - 获取表名
//============================================================
/**
 获取表名
 
 @param cls 类名
 @return 表名
 */
extension XJSqlite3ModelManager {
    class func xj_getClassName(cls: AnyClass) -> String {
        let str = NSStringFromClass(cls)
        var arr: [String] = [String]()
        if (str.range(of: ".") != nil) {
            arr = str.components(separatedBy: ".")
        }
        return arr.last ?? ""
    }
}





//============================================================
//       Check 2 - 字段名和类型拼接在一起
//============================================================
/**
 变量名字和类型拼接在一起 "age integer,name text, score real"
 
 @param cls 类名
 @return "age integer,name text, score real"
 */
extension XJSqlite3ModelManager {
   class func xj_columnNameTypeDict<T: NSObject>(cls: T.Type) -> String where T: XJSqlite3ModelProtocol{
        let dict = XJSqlite3ModelManager.xj_getIvarNameSqlite3TypeDictFromClass(cls: cls)
        var resultArray: [String] = [String]()
        for (key, value) in dict {
            resultArray.append("\(key) \(value)")
        }
        return (resultArray as! NSMutableArray).componentsJoined(by: ",")
    }
}





//============================================================
//       Check 3 - 获取模型中的所有的属性、并且排序
//============================================================
/**
 获取模型中的所有的属性、并且排序
 
 @param cls 类名
 @return 新表中所有字段
 */
extension XJSqlite3ModelManager {
    class func  xj_getAllColumnNameWithSored<T: NSObject>(cls: T.Type) -> [String] where T: XJSqlite3ModelProtocol {
        let dict = XJSqlite3ModelManager.xj_getIvarNameTypeDictFromClass(cls: cls)
        var keyArray = [String]()
        for key in dict.keys {
            keyArray.append(key)
        }
        keyArray = keyArray.sorted { (s1, s2) -> Bool in
            return s1 < s2
        }
        return keyArray
    }
}




extension XJSqlite3ModelManager {
    
    //============================================================
    //       Check 4.1 - 将模型中字段类型转化为sqlite3类型字典[name : "text", age: "integer", id: "integer"]
    //============================================================
    fileprivate class func xj_getIvarNameSqlite3TypeDictFromClass<T: NSObject>(cls: T.Type) -> [String: String] where T: XJSqlite3ModelProtocol{
        var dict = XJSqlite3ModelManager.xj_getIvarNameTypeDictFromClass(cls: cls)
        var tempDict = XJSqlite3ModelManager.xj_ocTypeToSqlite3TypeDict()
        for (key,value) in dict {
            dict[key] = tempDict[value]
        }
        return dict
    }
    
    //============================================================
    //       Check 4.2 - 获取模型中的字段和类型[name :  String, age: Int, id: Int]
    //============================================================
    class func xj_getIvarNameTypeDictFromClass<T: NSObject>(cls: T.Type) -> [String : String] where T: XJSqlite3ModelProtocol{
        // 1:获取这个类里面、所有的字段名以及类型
        var count: UInt32 = 0
        let propertys = class_copyPropertyList(cls, &count)
        var dict: [String: String] = [String: String]()
        
        // 忽略数组
        var ignoreArray: [String] = [String]()
        if cls.responds(to: #selector(cls.ignoreColumnName)){
            ignoreArray = cls.ignoreColumnName!()
        }
        
        for i in 0..<Int(count) {
            // 1.1 获取字段名
            let property = propertys?[i]
            var ivarName: String = ""
            if let name = property_getName(property) {
                if let varName = String(cString: name, encoding: .utf8) {
                    ivarName = varName
                }
            }
            
            // 1.2 忽略字段处理:continue 后面跳过、但是循环从新继续
            if ignoreArray.contains(ivarName) {
                continue
            }
            
            // 1.2 获取类型
            var ivarType: String = ""
            if let type = property_getAttributes(property) {
                if let varType = String(cString: type, encoding: .utf8) {
                    ivarType = varType
                }
            }
            dict[ivarName] = XJSqlite3ModelManager.xj_dealPropertyIvarType(varType: ivarType)
        }
        return dict
    }
    
    
    //============================================================
    //       Check 4.3 - 单独处理模型中字段类型的截取
    //============================================================
    fileprivate class func xj_dealPropertyIvarType(varType: String) -> String {
        let arrType = varType.components(separatedBy: ",")
        guard var newType = arrType.first else {
            return ""
        }
        newType = newType.trimmingCharacters(in: CharacterSet.init(charactersIn: "T"))
        newType = newType.trimmingCharacters(in: CharacterSet.init(charactersIn: "@\""))
        return newType
    }
    
    
    //============================================================
    //       Check 4.4 - 反射表格：字段类型转化
    //============================================================
    fileprivate class func xj_ocTypeToSqlite3TypeDict() -> [String : String] {
        return [
                "f": "real", // Float
                "d": "real", // Double
            
                "q": "integer",  // int
                "Q": "integer",  // long long
                "B": "integer",  // bool
            
                "NSData": "blob",
                "NSString": "text",
                "NSDictionary": "text",
                "NSArray": "text",
                "UIColor": "blob"
               ]
    }
}


